{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#-*- coding: utf-8 -*-"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 文件的读写"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "春天刮着风\n",
      "秋天下着雨\n",
      "春风秋雨多少海誓山盟随风远去\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#文件的读写\n",
    "#文件打开  文件打开的通用格式  使用with块的好处是：执行完毕后，自动对文件进行close操作\n",
    "#with open(\"文件路径\",\"打开模式\",encoding=\"操作文件的字符编码\") as f:\n",
    "#    \"\"\"对文件进行相应的读写操作\"\"\"\n",
    "\n",
    "#一个简单的文件读取\n",
    "with open(r\"test.txt\",\"r\",encoding=\"utf-8\") as f:  #第一步 打开文件\n",
    "    text = f.read()                                                                                       #第二步 读取文件\n",
    "    print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "春天刮着风\n",
      "秋天下着雨\n",
      "春风秋雨多少海誓山盟随风远去\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#程序与文件在同一文件夹，文件路径可简化为文件名\n",
    "with open(r\"test.txt\",\"r\",encoding=\"utf-8\") as f:  #第一步 打开文件\n",
    "    text = f.read()                                #第二步 读取文件\n",
    "    print(text)\n",
    "\n",
    "#打开模式\n",
    "#\"r\" 只读模式 如果文件不存在 报错\n",
    "#\"w\" 覆盖写模式 如文件不存在 则创建；如文件存在，则完全覆盖原文件\n",
    "#\"x\" 创建写模式 如文件不存在 则创建；如文件存在 报错\n",
    "#\"a\" 追加写模式，如文件不存在，则创建；如文件存在，则在原文件后追加内容\n",
    "#\"b\" 二进制文件模式，不能单独使用，需要配合使用如\"rb\",\"wb\",\"ab\",该模式不需要指定encoding\n",
    "#\"t\" 文本文件模式，默认值 需配合使用，如 \"rt\",\"wt\",\"at\",一般省略，简写成 \"r\",\"w\",\"a\"\n",
    "#\"+\", 与\"r\",\"w\",\"x\",\"a\"配合使用，在原功能的基础上，增加读写功能\n",
    "#打开模式缺省 默认为只读模式\n",
    "\n",
    "\n",
    "#字符编码\n",
    "#万国码  utf-8  包含全世界所有国家需要用到的字符\n",
    "#中文编码 gbk 专门解决中文编码问题 windows系统下，如果缺省，则默认为gbk（所在区域的编码）\n",
    "#为清楚起见 除了处理二进制文件 建议不要缺省 encoding"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "春天刮着风\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#文件读取\n",
    "#逐行进行读取   f.readline\n",
    "with open(r\"test.txt\",\"r\",encoding=\"utf-8\") as f:\n",
    "    text = f.readline()\n",
    "    print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['春天刮着风\\n', '秋天下着雨\\n', '春风秋雨多少海誓山盟随风远去\\n']\n",
      "春天刮着风\n",
      "\n",
      "秋天下着雨\n",
      "\n",
      "春风秋雨多少海誓山盟随风远去\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#读入所有行，以每行为元素形成一个列表 -- f.readlines()\n",
    "with open(r\"test.txt\",\"r\",encoding=\"utf-8\") as f:\n",
    "    text = f.readlines()\n",
    "    print(text)  #注意每行末尾有换行符\n",
    "    \n",
    "with open(r\"test.txt\", \"r\", encoding=\"utf-8\") as f:\n",
    "        for text in f.readlines(): #遍历列表\n",
    "          print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "直接遍历f： 春天刮着风\n",
      "\n",
      "直接遍历f： 秋天下着雨\n",
      "\n",
      "直接遍历f： 春风秋雨多少海誓山盟随风远去\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#当文件内容过大时，read和readlines占用内存过大，不建议使用，readline用起来不太方便，此时可以直接遍历f\n",
    "with open(r\"test.txt\", \"r\", encoding=\"utf-8\") as f:\n",
    "    for text in f:                  #f本身就是一个可迭代对象，每次迭代都读取一行内容\n",
    "        print(\"直接遍历f：\",text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "414\n"
     ]
    }
   ],
   "source": [
    "#图片：二进制文件\n",
    "with open(\"test.jpg\",\"rb\") as f:\n",
    "    print(len(f.readlines()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "#文件的写入\n",
    "#向文件写入一个字符串或字节流（二进制）-- f.write\n",
    "with open(\"test.txt\",\"w\",encoding=\"utf-8\") as f:\n",
    "    f.write(\"你曾经对我说\\n\")     #文件不存在则创建一个，如果文件存在，新写入的内容会覆盖掉原内容，一定要注意\n",
    "    f.write(\"你永远爱着我\\n\")     #如需要换行，末尾添加换行符 \\n\n",
    "#追加写入\n",
    "with open(\"test.txt\",\"a\",encoding=\"utf-8\") as f:\n",
    "    f.write(\"你曾经对我说\\n\")    #追加模式\n",
    "#将一个元素为字符串的列表整体写入文件 -- f.writelines()\n",
    "ls = [\"春天刮着风\\n\",\"秋天下着雨\\n\",\"春风秋雨多少海誓山盟随风远去\\n\"]\n",
    "with open(\"test.txt\",\"w\",encoding=\"utf-8\") as f:\n",
    "    f.writelines(ls)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "#既读又写\n",
    "#\"r+\" 如果文件名不存在 则报错，指针在开始，如果要进行写操作，要把指针移动到末尾才能开始写，否则会覆盖前面内容\n",
    "with open(\"test1.txt\",\"r+\",encoding=\"utf-8\") as f:\n",
    "#    for line in f:\n",
    "#        print(line) 全部读一遍后，指针达到结尾\n",
    "     f.seek(0,2)   #或者可以将指针移动到末尾  f.seek(偏移字节数，位置(0:开始， 1：当前位置， 2：结尾))\n",
    "     text = [\"萧瑟秋风今又是，\\n\",\"换了人间。\\n\"] #将这两句追加到结尾\n",
    "     f.writelines(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "萧瑟秋风今又是，\n",
      "换了人间。\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#w+ 若文件不存在，则创建 若文件存在，会立即清空原内容\n",
    "with open(\"test1.txt\",\"w+\",encoding=\"utf-8\") as f:\n",
    "    text = [\"萧瑟秋风今又是，\\n\",\"换了人间。\\n\"]  #清空原内容\n",
    "    f.writelines(text)   #写入新内容，指针在最后\n",
    "    f.seek(0,0)  #指针移动到开始\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "萧瑟秋风今又是，\n",
      "换了人间。\n",
      "萧瑟秋风今又是，\n",
      "换了人间。\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#a+ 若文件不存在，则创建，指针在末尾 添加新内容，不会清空原内容\n",
    "with open(\"test1.txt\",\"a+\",encoding=\"utf-8\") as f:\n",
    "    text = [\"萧瑟秋风今又是，\\n\",\"换了人间。\\n\"]\n",
    "    f.writelines(text)   #指针在最后，追加新内容\n",
    "    f.seek(0,0)  #指针移动到开始\n",
    "    print(f.read())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 数据存储与读取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['编号，数学成绩，语文成绩']\n",
      "['1，98，88']\n",
      "['2，88，89']\n"
     ]
    }
   ],
   "source": [
    "#本节简单了解两种数据存储结构，csv和json\n",
    "#csv格式 由逗号将数据分开的字符序列，可以由excel打开\n",
    "#读取\n",
    "with open(\"成绩.csv\",\"r\",encoding=\"utf-8\") as f:\n",
    "    ls = []\n",
    "    for line in f:      #逐行读取\n",
    "        ls.append(line.strip(\"\\n\").split(\",\")) #去掉每行的换行符，然后用\",\"进行分割\n",
    "\n",
    "for res in ls:\n",
    "    print (res)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "#写入\n",
    "ls = [['编号','数学成绩','语文成绩'],['1','100','90'],['2','96','99']]\n",
    "with open(\"score.csv\",\"w\",encoding=\"utf-8\") as f:\n",
    "    for row in ls:\n",
    "        f.write(\",\".join(row)+\"\\n\") #用逗号组成字符串形式，末尾加换行符"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "#json格式 常被用来存储字典类型\n",
    "#写入 --dump()\n",
    "import json\n",
    "scores = {\"Peter\":{\"math\":96,\"physics\":98},\"Paul\":{\"math\":96,\"physics\":98}}\n",
    "with open(\"score.json\",\"w\",encoding=\"utf-8\") as f:   #写入整个对象\n",
    "    json.dump(scores,f,indent=4,ensure_ascii=False)  #indent 表示字符换行+缩进"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Peter {'math': 96, 'physics': 98}\n",
      "Paul {'math': 96, 'physics': 98}\n"
     ]
    }
   ],
   "source": [
    "#读取  --load\n",
    "with open(\"score.json\",\"r\",encoding=\"utf-8\") as f:\n",
    "    scores = json.load(f)\n",
    "    for k,v in scores.items():\n",
    "        print(k,v)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 异常处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0不可以被除！\n",
      "键不存在\n"
     ]
    }
   ],
   "source": [
    "#常见异常的产生\n",
    "#除0运算；找不到可读文件 FileNotFoundError；值错误 ValueError 传入一个不期望的值，即使这个值的类型是正确的；索引错误-IndexError，下标超出序列边界；类型错误 -typeError，传入对象类型与要求不符\n",
    "#当异常发生时，如不预先设定处理方法，程序就会中断,异常的处理  可提高程序的稳定性与可靠性\n",
    "# try_except  如果try内代码块顺利执行，except不被触发，如果try内代码块发生错误，触发except执行except内代码块\n",
    "#单分支\n",
    "x =10\n",
    "y = 0\n",
    "try:\n",
    "    z = x/y\n",
    "except ZeroDivisionError:    #一般来说会预测到出现什么错误\n",
    "    print(\"0不可以被除！\")\n",
    "\n",
    "#多分支\n",
    "ls = []\n",
    "d = {\"name\":\"andy\"}\n",
    "try:\n",
    "    d[\"age\"]\n",
    "except NameError:\n",
    "    print(\"变量名不存在\")\n",
    "except IndexError:\n",
    "    print(\"索引超出界限\")\n",
    "except KeyError:\n",
    "    print(\"键不存在\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "出错啦\n"
     ]
    }
   ],
   "source": [
    "#万能的Exception 所有错误的老祖宗 可以捕捉任何错误类型\n",
    "ls = []\n",
    "d = {\"name\":\"andy\"}\n",
    "try:\n",
    "    print (d[\"age\"])\n",
    "except Exception:\n",
    "    print(\"出错啦\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "错误值： name 'm' is not defined\n"
     ]
    }
   ],
   "source": [
    "#用as捕捉异常错误的值\n",
    "ls = []\n",
    "d = {\"name\":\"andy\"}\n",
    "try:\n",
    "    y = m\n",
    "except Exception as e: #虽然不能获得错误的具体类型，但是可以获得错误的值\n",
    "    print(\"错误值：\",e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "文件内容：\n",
      " 萧瑟秋风今又是，\n",
      "换了人间。\n",
      "萧瑟秋风今又是，\n",
      "换了人间。\n",
      "\n"
     ]
    }
   ],
   "source": [
    "#try_except_else 如果try模块执行，则else模块也执行，可以将else模块看做是try成功的额外奖赏,如果try内容报错，则else就不会执行\n",
    "try:\n",
    "    with open(\"test1.txt\",\"r\",encoding=\"utf-8\") as f:\n",
    "        text = f.read()\n",
    "except FileNotFoundError:\n",
    "    print(\"找不到该文件\")\n",
    "else:\n",
    "    print(\"文件内容：\\n\",text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "list index out of range\n",
      "不论触不触发异常，都将执行\n"
     ]
    }
   ],
   "source": [
    "#try_except_finally\n",
    "#无论try模块是否执行，finally最后都执行\n",
    "ls = []\n",
    "d = {\"name\":\"andy\"}\n",
    "try:\n",
    "    y = x\n",
    "    print (ls[3])\n",
    "    print (d[\"age\"])\n",
    "except Exception as e:\n",
    "    print (e)\n",
    "finally:\n",
    "    print(\"不论触不触发异常，都将执行\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 模块"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [],
   "source": [
    "#模块分类\n",
    "#python内置模块 时间库time 随机库random 容器数据类型collection 迭代数据类型 itertools\n",
    "#第三方库 数据分析numpy pandas 数据可视化 matplotlib 机器学习 scikit-learn 深度学习 tensorflow\n",
    "#自定义文件 单独的py文件； \n",
    "#包--文件夹内有多个py文件，再加上一个__init__.py文件（内容可以为空）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "程序运行用时：3.00秒\n"
     ]
    }
   ],
   "source": [
    "#模块的导入\n",
    "#导入整个模块：  import 模块名\n",
    "#调用方式： 模块名.函数名或类名\n",
    "import time\n",
    "start = time.time()\n",
    "time.sleep(3)\n",
    "end = time.time()\n",
    "print(\"程序运行用时：{:.2f}秒\".format(end-start))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[('A', '1'), ('A', '2'), ('A', '3'), ('B', '1'), ('B', '2'), ('B', '3')]\n"
     ]
    }
   ],
   "source": [
    "#从模块中导入类或函数 - from 模块 import 类名或函数名\n",
    "#调用方式：函数名或类名\n",
    "from itertools import product\n",
    "ls = list(product(\"AB\",\"123\"))\n",
    "print (ls)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "20\n",
      "0.6429685301469827\n"
     ]
    }
   ],
   "source": [
    "#一次导入多个 from function import fun1,fun2\n",
    "#导入模块中所有的类和函数  from 模块 import *\n",
    "#调用方式：函数名或类名\n",
    "from random import *\n",
    "print(randint(1,100))\n",
    "print(random())\n",
    "#模块的搜索查找路径\n",
    "#首先搜索内存中已经加载的模块，其次导入内置模块，最后导入sys.path路径中包含的模块\n",
    "# sys.path的第一个路径是当前执行文件所在的文件夹，若所需模块不在其中，则需要将模块的路径添加到sys.path\n",
    "#import sys\n",
    "#sys.path.append(\"C:\\\\xxx\\\\xxx\\\\xxx\") #注意是双斜杠"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}